#include "HttpServer.h"

#include "httplib.h"

#include <glog/logging.h>

using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;

HttpServer::HttpServer(const std::string &hostname, uint16_t port) : m_host(hostname), m_port(port)
{
    m_http_server = std::make_unique<httplib::Server>();
}

HttpServer::~HttpServer()
{
}

void HttpServer::httpErrorHandler(const httplib::Request &req, httplib::Response &res)
{
    auto fmt = "<h1 align=\"center\">%s<h1><hr/>";
    char buf[BUFSIZ];
    snprintf(buf, sizeof(buf), fmt, httplib::status_message(res.status));
    res.set_content(buf, "text/html");
}

void HttpServer::httpExceptionHandler(const httplib::Request &req, httplib::Response &res, std::exception_ptr ep)
{
    auto fmt = "<h1>Error 500</h1><p>%s</p>";
    char buf[BUFSIZ];
    try {
        std::rethrow_exception(ep);
    } catch (std::exception &e) {
        snprintf(buf, sizeof(buf), fmt, e.what());
    } catch (...) {
        snprintf(buf, sizeof(buf), fmt, "Unknown Exception");
    }
    res.set_content(buf, "text/html");
    res.status = httplib::StatusCode::InternalServerError_500;
}

void HttpServer::addController(BaseController *controller)
{
    m_controllers.push_back(controller);
    controller->bind(m_http_server.get());
}

bool HttpServer::start()
{
    std::cout << "启动 HTTP 服务, http://" << m_host << ":" << m_port << std::endl;

    m_http_server->set_payload_max_length(1024 * 1024 * 512); // 512M
    m_http_server->set_keep_alive_timeout(60);
    m_http_server->set_error_handler(std::bind(&HttpServer::httpErrorHandler, this, _1, _2));
    m_http_server->set_exception_handler(std::bind(&HttpServer::httpExceptionHandler, this, _1, _2, _3));
    return m_http_server->listen(m_host, m_port);
}
